package com.zz;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MarkdownDoc {

	private final File fileMarkdown; // Markdown文件
	private File fileImageDir; // 图片文件夹
	private final File dirParent; // Markdown文件所在的文件夹

	public MarkdownDoc(String strMarkdownPath) {
		fileMarkdown = new File(strMarkdownPath);
		if (!fileMarkdown.exists() || !fileMarkdown.isFile()) {
			throw new IllegalArgumentException("非法的Markdown文件路径");
		}

		if (!strMarkdownPath.toLowerCase().endsWith(".md")) {
			throw new IllegalArgumentException("非法的文件类型");
		}

		dirParent = fileMarkdown.getParentFile();

		String strMarkdownNameNoEx = Utils.getFileNameNoEx(fileMarkdown);

		String strImageDirName = "." + strMarkdownNameNoEx + ".assets";

		fileImageDir = new File(fileMarkdown.getParent(), strImageDirName);

		if (!fileImageDir.exists() || !fileImageDir.isDirectory()) {
			throw new IllegalArgumentException("图片文件夹不存在");
		}
	}

	/**
	 从图片文件夹获取所有图片的全路径，并组成ArrayList
	 @return imageAbsPathListInDir
	 */
	public File[] getImageFilesFromDir() {
		return fileImageDir.listFiles(pathname -> {
			String filename = pathname.getName().toLowerCase();
			return filename.endsWith(".png") || filename.endsWith(".jpg") || filename.endsWith(".gif") || filename.endsWith(".jpeg");
		});
	}

	/**
	 逐行读取Markdown文件，解析其中的md图片表达式和img标签
	 并用其中指向本地图片的path创建file的集合
	 @return localImageFileList
	 */
	public List<File> getLocalImageFileListFromMd() throws Exception {
		ArrayList<File> allImageList = new ArrayList<>();
		// BugFix：乱码导致图片被误删，且找不回来…
		BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(fileMarkdown), StandardCharsets.UTF_8));
		String line;
		while ((line = reader.readLine()) != null) {
			// 进行Markdown图片表达式解析
			List<File> imageListInImgEx = getAllImagePathInLine(line);
			allImageList.addAll(imageListInImgEx);
			// 进行img标签解析
			List<File> imageListInImgEle = getImgSrc(line);
			allImageList.addAll(imageListInImgEle);
		}
		return allImageList;
	}

	/**
	 在一行内查找所有的图片表达式，并返回指向本地文件的file的集合
	 .* 贪婪匹配
	 .*? 懒惰模式
	 @param strLine 一行文本
	 @return imagePathList
	 */
	private List<File> getAllImagePathInLine(String strLine) {
		List<File> imageList = new ArrayList<>();
		Pattern pattern = Pattern.compile(".*!\\[.*?]\\(.*?\\).*"); // 匹配一行中的所有Markdown图片表达式
		Matcher m = pattern.matcher(strLine);
		int groupId = 0; // 匹配结果的id
		while (m.find()) {
			String imagePath = getImagePathFromReg(m.group(groupId++)); // 从一个匹配结果中获取图片path
			if (imagePath != null) {
				imageList.add(new File(dirParent, imagePath));
			}
		}
		return imageList;
	}

	/**
	 从一个图片表达式内获取图片path（一个表达式只有一个图片path）
	 .* 贪婪匹配
	 .*? 懒惰模式
	 @param imageReg imageReg
	 @return imagePath
	 */
	private String getImagePathFromReg(String imageReg) {
		Pattern pattern = Pattern.compile("\\(.*?\\)");// 匹配被小括号包围的字符串（带括号）
		Matcher m = pattern.matcher(imageReg);
		if (m.find()) {
			String result = m.group(0); // 图片path（带括号）
			result = result.substring(1, result.length() - 1); // 去括号
			if (result.startsWith("http")) { // 如果是网络图片就算了
				return null;
			}
			return result; // 真正的本地图片path
		}
		return null;
	}

	/**
	 提取一行文本中所有img标签的src（不要网络图片），即它们的图片的path
	 @param line 一行文本
	 @return imagePathList
	 */
	private List<File> getImgSrc(String line) {
		String img = "";
		Pattern p_image;
		Matcher m_image;
		List<File> imageList = new ArrayList<>();
		String regEx_img = "<img.*src\\s*=\\s*(.*?)[^>]*?>";
		p_image = Pattern.compile(regEx_img, Pattern.CASE_INSENSITIVE);
		m_image = p_image.matcher(line);
		while (m_image.find()) {
			img = img + "," + m_image.group();
			Matcher m = Pattern.compile("src\\s*=\\s*\"?(.*?)(\"|>|\\s+)").matcher(img);
			while (m.find()) {
				String group = m.group(1);
				if (group.startsWith("http")) { // 如果是网络图片就算了
					continue;
				}
				imageList.add(new File(dirParent, group));
			}
		}
		return imageList;
	}
}
